home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / DEMOS / NEWAVE / TEXTURE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  7.4 KB  |  284 lines

  1.  
  2. /* texture.c - by David Blythe, SGI */
  3.  
  4. /* read_texture is a simplistic routine for reading an SGI .rgb image file. */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h> 
  8. #include <string.h>
  9. #include <GL/glut.h>
  10.  
  11. void
  12. bwtorgba(unsigned char *b,unsigned char *l,int n) {
  13.     while(n--) {
  14.         l[0] = *b;
  15.         l[1] = *b;
  16.         l[2] = *b;
  17.         l[3] = 0xff;
  18.         l += 4; b++;
  19.     }
  20. }
  21.  
  22. void
  23. rgbtorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) {
  24.     while(n--) {
  25.         l[0] = r[0];
  26.         l[1] = g[0];
  27.         l[2] = b[0];
  28.         l[3] = 0xff;
  29.         l += 4; r++; g++; b++;
  30.     }
  31. }
  32.  
  33. void
  34. rgbatorgba(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *a,unsigned char *l,int n) {
  35.     while(n--) {
  36.         l[0] = r[0];
  37.         l[1] = g[0];
  38.         l[2] = b[0];
  39.         l[3] = a[0];
  40.         l += 4; r++; g++; b++; a++;
  41.     }
  42. }
  43.  
  44. typedef struct _ImageRec {
  45.     unsigned short imagic;
  46.     unsigned short type;
  47.     unsigned short dim;
  48.     unsigned short xsize, ysize, zsize;
  49.     unsigned int min, max;
  50.     unsigned int wasteBytes;
  51.     char name[80];
  52.     unsigned long colorMap;
  53.     FILE *file;
  54.     unsigned char *tmp, *tmpR, *tmpG, *tmpB;
  55.     unsigned long rleEnd;
  56.     unsigned int *rowStart;
  57.     int *rowSize;
  58. } ImageRec;
  59.  
  60. static void
  61. ConvertShort(unsigned short *array, unsigned int length) {
  62.     unsigned short b1, b2;
  63.     unsigned char *ptr;
  64.  
  65.     ptr = (unsigned char *)array;
  66.     while (length--) {
  67.         b1 = *ptr++;
  68.         b2 = *ptr++;
  69.         *array++ = (b1 << 8) | (b2);
  70.     }
  71. }
  72.  
  73. static void
  74. ConvertUint(unsigned *array, unsigned int length) {
  75.     unsigned int b1, b2, b3, b4;
  76.     unsigned char *ptr;
  77.  
  78.     ptr = (unsigned char *)array;
  79.     while (length--) {
  80.         b1 = *ptr++;
  81.         b2 = *ptr++;
  82.         b3 = *ptr++;
  83.         b4 = *ptr++;
  84.         *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4);
  85.     }
  86. }
  87.  
  88. static ImageRec *ImageOpen(char *fileName)
  89. {
  90.     union {
  91.         int testWord;
  92.         char testByte[4];
  93.     } endianTest;
  94.     ImageRec *image;
  95.     int swapFlag;
  96.     int x;
  97.  
  98.     endianTest.testWord = 1;
  99.     if (endianTest.testByte[0] == 1) {
  100.         swapFlag = 1;
  101.     } else {
  102.         swapFlag = 0;
  103.     }
  104.  
  105.     image = (ImageRec *)malloc(sizeof(ImageRec));
  106.     if (image == NULL) {
  107.         fprintf(stderr, "Out of memory!\n");
  108.         exit(1);
  109.     }
  110.     if ((image->file = fopen(fileName, "rb")) == NULL) {
  111.         perror(fileName);
  112.         exit(1);
  113.     }
  114.  
  115.     fread(image, 1, 12, image->file);
  116.  
  117.     if (swapFlag) {
  118.         ConvertShort(&image->imagic, 6);
  119.     }
  120.  
  121.     image->tmp = (unsigned char *)malloc(image->xsize*256);
  122.     image->tmpR = (unsigned char *)malloc(image->xsize*256);
  123.     image->tmpG = (unsigned char *)malloc(image->xsize*256);
  124.     image->tmpB = (unsigned char *)malloc(image->xsize*256);
  125.     if (image->tmp == NULL || image->tmpR == NULL || image->tmpG == NULL ||
  126.         image->tmpB == NULL) {
  127.         fprintf(stderr, "Out of memory!\n");
  128.         exit(1);
  129.     }
  130.  
  131.     if ((image->type & 0xFF00) == 0x0100) {
  132.         x = image->ysize * image->zsize * (int) sizeof(unsigned);
  133.         image->rowStart = (unsigned *)malloc(x);
  134.         image->rowSize = (int *)malloc(x);
  135.         if (image->rowStart == NULL || image->rowSize == NULL) {
  136.             fprintf(stderr, "Out of memory!\n");
  137.             exit(1);
  138.         }
  139.         image->rleEnd = 512 + (2 * x);
  140.         fseek(image->file, 512, SEEK_SET);
  141.         fread(image->rowStart, 1, x, image->file);
  142.         fread(image->rowSize, 1, x, image->file);
  143.         if (swapFlag) {
  144.             ConvertUint(image->rowStart, x/(int) sizeof(unsigned));
  145.             ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int));
  146.         }
  147.     }
  148.     return image;
  149. }
  150.  
  151. static void
  152. ImageClose(ImageRec *image) {
  153.     fclose(image->file);
  154.     free(image->tmp);
  155.     free(image->tmpR);
  156.     free(image->tmpG);
  157.     free(image->tmpB);
  158.     free(image);
  159. }
  160.  
  161. static void
  162. ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) {
  163.     unsigned char *iPtr, *oPtr, pixel;
  164.     int count;
  165.  
  166.     if ((image->type & 0xFF00) == 0x0100) {
  167.         fseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET);
  168.         fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize],
  169.               image->file);
  170.  
  171.         iPtr = image->tmp;
  172.         oPtr = buf;
  173.         for (;;) {
  174.             pixel = *iPtr++;
  175.             count = (int)(pixel & 0x7F);
  176.             if (!count) {
  177.                 return;
  178.             }
  179.             if (pixel & 0x80) {
  180.                 while (count--) {
  181.                     *oPtr++ = *iPtr++;
  182.                 }
  183.             } else {
  184.                 pixel = *iPtr++;
  185.                 while (count--) {
  186.                     *oPtr++ = pixel;
  187.                 }
  188.             }
  189.         }
  190.     } else {
  191.         fseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize),
  192.               SEEK_SET);
  193.         fread(buf, 1, image->xsize, image->file);
  194.     }
  195. }
  196.  
  197. unsigned *
  198. read_texture(char *name, int *width, int *height, int *components) {
  199.     unsigned *base, *lptr;
  200.     unsigned char *rbuf, *gbuf, *bbuf, *abuf;
  201.     ImageRec *image;
  202.     int y;
  203.  
  204.     image = ImageOpen(name);
  205.     
  206.     if(!image)
  207.         return NULL;
  208.     (*width)=image->xsize;
  209.     (*height)=image->ysize;
  210.     (*components)=image->zsize;
  211.     base = (unsigned *)malloc(image->xsize*image->ysize*sizeof(unsigned));
  212.     rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  213.     gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  214.     bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  215.     abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char));
  216.     if(!base || !rbuf || !gbuf || !bbuf)
  217.       return NULL;
  218.     lptr = base;
  219.     for(y=0; y<image->ysize; y++) {
  220.         if(image->zsize>=4) {
  221.             ImageGetRow(image,rbuf,y,0);
  222.             ImageGetRow(image,gbuf,y,1);
  223.             ImageGetRow(image,bbuf,y,2);
  224.             ImageGetRow(image,abuf,y,3);
  225.             rgbatorgba(rbuf,gbuf,bbuf,abuf,(unsigned char *)lptr,image->xsize);
  226.             lptr += image->xsize;
  227.         } else if(image->zsize==3) {
  228.             ImageGetRow(image,rbuf,y,0);
  229.             ImageGetRow(image,gbuf,y,1);
  230.             ImageGetRow(image,bbuf,y,2);
  231.             rgbtorgba(rbuf,gbuf,bbuf,(unsigned char *)lptr,image->xsize);
  232.             lptr += image->xsize;
  233.         } else {
  234.             ImageGetRow(image,rbuf,y,0);
  235.             bwtorgba(rbuf,(unsigned char *)lptr,image->xsize);
  236.             lptr += image->xsize;
  237.         }
  238.     }
  239.     ImageClose(image);
  240.     free(rbuf);
  241.     free(gbuf);
  242.     free(bbuf);
  243.     free(abuf);
  244.  
  245.     return (unsigned *) base;
  246. }
  247.  
  248. void imgLoad(char *filenameIn, int borderIn, GLfloat borderColorIn[4],
  249.   int *wOut, int *hOut, GLubyte ** imgOut)
  250. {
  251.   int border = borderIn;
  252.   int width, height;
  253.   int w, h;
  254.   GLubyte *image, *img, *p;
  255.   int i, j, components;
  256.  
  257.   image = (GLubyte *) read_texture(filenameIn, &width, &height, &components);
  258.   w = width + 2 * border;
  259.   h = height + 2 * border;
  260.   img = (GLubyte *) calloc(w * h, 4 * sizeof(unsigned char));
  261.  
  262.   p = img;
  263.   for (j = -border; j < height + border; ++j) {
  264.     for (i = -border; i < width + border; ++i) {
  265.       if (0 <= j && j <= height - 1 && 0 <= i && i <= width - 1) {
  266.         p[0] = image[4 * (j * width + i) + 0];
  267.         p[1] = image[4 * (j * width + i) + 1];
  268.         p[2] = image[4 * (j * width + i) + 2];
  269.         p[3] = 0xff;
  270.       } else {
  271.         p[0] = borderColorIn[0] * 0xff;
  272.         p[1] = borderColorIn[1] * 0xff;
  273.         p[2] = borderColorIn[2] * 0xff;
  274.         p[3] = borderColorIn[3] * 0xff;
  275.       }
  276.       p += 4;
  277.     }
  278.   }
  279.   free(image);
  280.   *wOut = w;
  281.   *hOut = h;
  282.   *imgOut = img;
  283. }
  284.